home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-01
/
castools.zip
/
REMOVEFR.C
< prev
next >
Wrap
Text File
|
1990-02-13
|
6KB
|
242 lines
/*
REMOVEFR.C Function PbRemoverFromGroup: Removers a person entry from
a group entry.
INPUT: Phonebook structure, and the record id's of the person and group
entries.
OUTPUT: If successful, removes the person from the group's members list, and
removes the group from the person's members list. If the change in
membership affects the group's HardwareType, that field is changed.
*/
#include <stdio.h>
#include <malloc.h>
#include <phonebk.h>
int pascal PbRemoveFromGroup(PB *pb, int GroupID, int MemberID)
{
int i, j, k;
PBE *group = NULL,
*person = NULL;
int retval = FAIL;
int writ; /* for return from fwrite() */
LONGWORD offset,
group_offset,
person_offset;
int temperrno = 0; /* for saving Pberrno aside */
BYTE hasccc = HASCCC; /* for changing a group h/w type */
Pberrno = 0; /* Initially, always reset */
/* First, check params */
if (pb == NULL) {
Pberrno = INVALIDPARAMETER;
return(NULL);
}
if ((GroupID < 0) ||
(GroupID > 999)) {
Pberrno = INVALIDPARAMETER;
return(NULL);
}
if ((MemberID < 0) ||
(MemberID > 999)) {
Pberrno = INVALIDPARAMETER;
return(NULL);
}
/* Check that this slight increase of 'free bytes' does not go the limit */
if ((pb->header.FreeBytes + 2*sizeof(int)) > MAXUNUSEDBYTES) {
Pberrno = TOOMANYFREEBYTES;
}
/* Fetch the entries involved */
if (!(group = PbGetEntry(pb, NULL, NULL, GroupID))) {
goto getout;
}
group_offset = OffsetOfEntry(pb, GroupID);
if (!(person = PbGetEntry(pb, NULL, NULL, MemberID))) {
goto getout;
}
person_offset = OffsetOfEntry(pb, MemberID);
/* Check that the group IS a group and the person IS a person */
if (group->type != GROUPENTRY) {
Pberrno = GROUPCANTBEMEMBER;
goto getout;
}
if (person->type != PERSONENTRY) {
Pberrno = PERSONCANTHAVEMEMBER;
goto getout;
}
/* Check that each IS in the others members list, and set indexes to them */
for (i=0; i<group->members; i++) {
if (group->MemberList[i] == MemberID) {
break;
}
}
if (i == group->members) {
Pberrno = GROUPDOESNTHAVEMEMBER;
goto getout;
}
for (j=0; j<person->members; j++) {
if (person->MemberList[j] == GroupID) {
break;
}
}
if (j == person->members) {
Pberrno = MEMBERDOESNTHAVEGROUP;
goto getout;
}
/* Check if this will affect the hardware type of the group */
if ((group->HardwareType == FAXONLY) && (person->HardwareType == FAXONLY)) {
/* check all members except the current one */
for (k=0; k<group->members; k++) {
if (group->MemberList[k] != MemberID) {
if (HardwareTypeOf(pb, group->MemberList[k], &offset) == FAXONLY) {
break;
}
}
}
/* If all other members of the group were HASCCC, time to change group */
if (k == group->members) {
if (fseek(pb->fp, group_offset + 7L, SEEK_SET)) {
Pberrno = FSEEKERROR;
goto getout;
}
writ = fwrite(&hasccc, sizeof(BYTE), 1, pb->fp);
if (writ != 1) {
Pberrno = CANTWRITE;
goto getout;
}
}
}
/* ...remove the membership ID's by writes to the fields on the file */
/* Do this by writing the last member in the list over the one being removed*/
offset = group_offset + group->length -
((group->members - i) * sizeof(int));
if (fseek(pb->fp, offset, SEEK_SET)) {
Pberrno = FSEEKERROR;
goto getout;
}
writ = fwrite(&group->MemberList[group->members - 1],
sizeof(int),
1,
pb->fp);
if (writ != 1) {
Pberrno = CANTWRITE;
goto getout;
}
/* Now, update the length */
if (fseek(pb->fp, group_offset + 4L, SEEK_SET)) {
Pberrno = FSEEKERROR;
goto getout;
}
group->length -= sizeof(int);
writ = fwrite(&group->length, sizeof(int), 1, pb->fp);
if (writ != 1) {
Pberrno = CANTWRITE;
goto getout;
}
/* and finally update the members count */
group->members--;
if (fseek(pb->fp, group_offset + 2L, SEEK_SET)) {
Pberrno = FSEEKERROR;
goto getout;
}
writ = fwrite(&group->members, sizeof(int), 1, pb->fp);
if (writ != 1) {
Pberrno = CANTWRITE;
goto getout;
}
/* Now, for the person entry's fields */
offset = person_offset + person->length -
((person->members - j) * sizeof(int));
if (fseek(pb->fp, offset, SEEK_SET)) {
Pberrno = FSEEKERROR;
goto getout;
}
writ = fwrite(&person->MemberList[person->members - 1],
sizeof(int),
1,
pb->fp);
if (writ != 1) {
Pberrno = CANTWRITE;
goto getout;
}
/* Now, update the length */
if (fseek(pb->fp, person_offset + 4L, SEEK_SET)) {
Pberrno = FSEEKERROR;
goto getout;
}
person->length -= sizeof(int);
writ = fwrite(&person->length, sizeof(int), 1, pb->fp);
if (writ != 1) {
Pberrno = CANTWRITE;
goto getout;
}
/* and finally update the members count */
person->members--;
if (fseek(pb->fp, person_offset + 2L, SEEK_SET)) {
Pberrno = FSEEKERROR;
goto getout;
}
writ = fwrite(&person->members, sizeof(int), 1, pb->fp);
if (writ != 1) {
Pberrno = CANTWRITE;
goto getout;
}
/* Tweak the phonebook's 'free bytes' field */
if (fseek(pb->fp, 6L, SEEK_SET)) {
Pberrno = FSEEKERROR;
goto getout;
}
pb->header.FreeBytes += 2 * sizeof(int);
writ = fwrite(&pb->header.FreeBytes, sizeof(BYTE), 1, pb->fp);
if (writ != 1) {
Pberrno = CANTWRITE;
goto getout;
}
if (!group->members) { /* last member: remove group */
if (!(PbRemoveEntry(pb, GroupID))) {
goto getout;
}
}
/* If we got here, all went well! */
retval = SUCCESS;
getout:
/* first save Pberrno aside because PbFreePBE would reset it */
if (Pberrno) {
temperrno = Pberrno;
}
if (group) {
PbFreePBE(pb, group);
}
if (person) {
PbFreePBE(pb, person);
}
if (temperrno) {
Pberrno = temperrno;
}
return(retval);
}